package com.party.core.service.gatherForm.biz;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.party.common.constant.Constant;
import com.party.common.utils.LangUtils;
import com.party.common.utils.PinyinUtil;
import com.party.common.utils.StringUtils;
import com.party.core.model.gatherForm.*;
import com.party.core.service.cos.CosBizService;
import com.party.core.service.gatherForm.IGatherFormInfoService;
import com.party.core.service.gatherForm.IGatherFormOptionService;
import com.party.core.service.gatherForm.IGatherFormService;
import com.party.core.service.gatherForm.IGatherProjectService;
import com.party.core.utils.MyBeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 项目biz
 * Created by yifeng
 *
 * @date 2018/5/8 0008
 * @time 下午 14:21
 */
@Service
public class GatherProjectBizService {
    @Autowired
    private IGatherFormService gatherFormService;
    @Autowired
    private IGatherFormOptionService gatherFormOptionService;
    @Autowired
    private IGatherProjectService gatherProjectService;
    @Autowired
    private IGatherFormInfoService gatherFormInfoService;
    @Autowired
    private CosBizService cosBizService;

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 获取项目表单项
     *
     * @param targetId 业务id
     * @return
     */
    public Map<String, Object> getProjectBiz(String targetId) {
        GatherProject db = this.getProjectByTargetId(targetId);
        if (db != null) {
            return this.getFormItems(db.getId(), db.getQuantity());
        }
        return null;
    }

    /**
     * 根据业务id获取项目
     *
     * @param targetId 业务id
     * @return
     */
    public GatherProject getProjectByTargetId(String targetId) {
        GatherProject db = gatherProjectService.findByTargetId(targetId);
        return db;
    }

    /**
     * 保存业务项目
     *
     * @param gatherProject
     */
    public void saveProjectBiz(GatherProject gatherProject) throws Exception {
        if (null != gatherProject.getItems() && gatherProject.getItems().size() > 0) {
            String projectId;
            GatherProject db = gatherProjectService.findByTargetId(gatherProject.getTargetId());
            if (db == null) {
                projectId = gatherProjectService.insert(gatherProject);
            } else {
                MyBeanUtils.copyBeanNotNull2Bean(gatherProject, db);
                gatherProjectService.update(db);
                projectId = db.getId();
            }

            this.saveFormItems(gatherProject.getItems(), projectId, gatherProject.getCreateBy(), null);
        }
    }

    /**
     * 保存表单项
     *
     * @param items     表单项
     * @param projectId 项目id
     * @param memberId  用户id
     * @param newFieldIds
     * @throws Exception
     */
    public void saveFormItems(List<GatherForm> items, String projectId, String memberId, List<String> newFieldIds) throws Exception {
        if (null == newFieldIds) {
            newFieldIds = Lists.newArrayList();
        }
        if (null != items && items.size() > 0) {
            for (GatherForm gatherForm : items) {
                if (Constant.FIELD_RESOURCE.equals(gatherForm.getCategory()) || Constant.FIELD_RESOURCELINK.equals(gatherForm.getCategory())) {
                    continue;
                }
                if (StringUtils.isEmpty(gatherForm.getRequired())) {
                    gatherForm.setRequired("false");
                }
                String gatherFormId = gatherForm.getId();
                if (StringUtils.isEmpty(gatherForm.getId())) {
                    gatherForm.setMaxIndex(new Integer(1));
                    gatherForm.setCreateBy(memberId);
                    gatherForm.setUpdateBy(memberId);
                    gatherForm.setProjectId(projectId);
                    gatherFormId = gatherFormService.insert(gatherForm);
                } else {
                    GatherForm t = gatherFormService.get(gatherForm.getId());
                    MyBeanUtils.copyBeanNotNull2Bean(gatherForm, t);
                    if (StringUtils.isEmpty(gatherForm.getIsSetMultiple())) {
                        t.setMaxNumber(null);
                        t.setIsSetMultiple(null);
                    }
                    if (StringUtils.isEmpty(gatherForm.getIsSetSize())) {
                        t.setMaxSize(null);
                        t.setIsSetSize(null);
                    }
                    gatherFormService.update(t);
                }
                newFieldIds.add(gatherFormId);
                if (null != gatherForm.getSubitems()) {
                    gatherFormOptionService.deleteByField(gatherForm.getId());
                    for (GatherFormOption option : gatherForm.getSubitems()) {
                        option.setId(null);
                        option.setCreateBy(memberId);
                        option.setFieldId(gatherFormId);
                        gatherFormOptionService.insert(option);
                    }
                }
            }

            List<GatherForm> gatherForms = gatherFormService.list(new GatherForm(projectId));
            List<String> oldFieldIds = LangUtils.transform(gatherForms, new Function<GatherForm, String>() {
                @Override
                public String apply(GatherForm input) {
                    return input.getId();
                }
            });

            oldFieldIds.removeAll(newFieldIds);

            for (String fieldId : oldFieldIds) {
                gatherFormOptionService.deleteByField(fieldId);
                gatherFormService.delete(fieldId);
            }
        }
    }

    /**
     * 获取表单项
     *
     * @param projectId 项目id
     * @param quantity  收集数量
     * @return
     */
    public Map<String, Object> getFormItems(String projectId, Long quantity) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("deleteStatus", quantity > 0 ? false : true);

        List<GatherForm> fields = this.getFormItems(projectId, false);
        params.put("fields", fields);
        return params;
    }

    /**
     * 获取表单项
     *
     * @param projectId 项目id
     * @return
     */
    public List<GatherForm> getFormItems(String projectId, boolean isMobile) {
        List<GatherForm> fields = gatherFormService.list(new GatherForm(projectId));
        for (GatherForm gatherForm : fields) {
            if (gatherForm.getType().equals(FormType.CHECKBOX.getValue()) || gatherForm.getType().equals(FormType.RADIO.getValue())
                    || gatherForm.getType().equals(FormType.SELECT.getValue())) {
                List<GatherFormOption> subitems = gatherFormOptionService.list(new GatherFormOption(gatherForm.getId()));
                if (isMobile) {
                    List<String> itemNames = LangUtils.transform(subitems, new Function<GatherFormOption, String>() {
                        @Override
                        public String apply(GatherFormOption input) {
                            return input.getName();
                        }
                    });
                    gatherForm.setSubItemNames(itemNames);
                } else {
                    gatherForm.setSubitems(subitems);
                }
            }
        }
        return fields;
    }

    /**
     * 保存表单填写信息
     *
     * @param infoItems 填写信息
     * @param projectId 项目id
     * @param memberId  用户id
     * @param targetId  业务id
     */
    public GatherProject saveFormInfoBiz(List<GatherFormInfo> infoItems, String projectId,
                                         String memberId, String targetId, boolean isNew) {
        if (isNew) {
            this.saveFormInfoBiz(infoItems, projectId, memberId, targetId);
        } else {
            this.deleteInfoByTargetId(targetId);
            this.saveFormInfo(infoItems, projectId, memberId, targetId);
        }
        return null;
    }

    /**
     * 保存表单填写信息
     *
     * @param infoItems 填写信息
     * @param projectId 项目id
     * @param memberId  用户id
     * @param targetId  业务id
     */
    public GatherProject saveFormInfoBiz(List<GatherFormInfo> infoItems, String projectId,
                                         String memberId, String targetId) {
        this.saveFormInfo(infoItems, projectId, memberId, targetId);
        GatherProject dbProject = gatherProjectService.get(projectId);
        dbProject.setQuantity(dbProject.getQuantity() + 1);
        gatherProjectService.update(dbProject);

        return dbProject;
    }

    /**
     * 保存表单填写信息
     *
     * @param infoItems 填写信息
     * @param projectId 项目id
     * @param memberId  用户id
     * @param targetId  业务id
     */
    public void saveFormInfo(List<GatherFormInfo> infoItems, String projectId,
                             String memberId, String targetId) {
        if (null != infoItems) {
            Integer maxIndex = gatherFormInfoService.getMaxIndex(projectId);
            for (GatherFormInfo info : infoItems) {
                if (StringUtils.isEmpty(info.getFieldValue())) {
                    info.setFieldValue(" ");
                } else {
                    info.setFieldValue(PinyinUtil.filterEmoji(info.getFieldValue(), ""));
                }
                if (StringUtils.isEmpty(info.getId())) {
                    info.setMaxIndex(null == maxIndex ? 1 : maxIndex + 1);
                    info.setProjectId(projectId);
                    info.setCreateBy(memberId);
                    info.setUpdateBy(memberId);
                    info.setTargetId(targetId);
                    gatherFormInfoService.insert(info);
                }
            }
        }
    }

    /**
     * 根据业务id获取表单项
     *
     * @param targetId 业务id
     * @return
     */
    public Map<String, Object> findByTargetId(String targetId) {
        Map<String, Object> params = Maps.newHashMap();
        GatherProject gatherProject = gatherProjectService.findByTargetId(targetId);
        if (gatherProject != null) {
            List<GatherForm> gatherForms = this.getFormItems(gatherProject.getId(), true);
            params.put("projectId", gatherProject.getId());
            params.put("items", gatherForms);
        }
        return params;
    }

    public void deleteInfoByTargetId(String targetId) {
        gatherFormInfoService.deleteByTargetId(targetId);
    }

    /**
     * 删除信息收集项目
     *
     * @param targetId  业务id
     * @param projectId 项目id
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean deleteProjectBiz(String targetId, String projectId, String uploadPath) {
        boolean endResult = true;
        GatherProject gatherProject = null;
        try {
            if (StringUtils.isNotEmpty(targetId)) {
                gatherProject = gatherProjectService.findByTargetId(targetId);
            }
            if (StringUtils.isNotEmpty(projectId)) {
                gatherProject = gatherProjectService.get(projectId);
            }
            if (gatherProject == null) {
                endResult = false;
                return endResult;
            }
            if (gatherProject != null) {
                List<GatherForm> gatherForms = gatherFormService.findByProjectId(gatherProject.getId());
                gatherForms.forEach(new Consumer<GatherForm>() {
                    @Override
                    public void accept(GatherForm gatherForm) {
                        gatherFormOptionService.deleteByField(gatherForm.getId());
                    }
                });
                gatherFormService.deleteByProject(gatherProject.getId());
                gatherFormInfoService.deleteByProjectId(gatherProject.getId(), null);
                gatherProjectService.delete(gatherProject.getId());
            }
        } catch (Exception e) {
            endResult = false;
            logger.error("删除自定义信息收集项目异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } finally {
            try {
                String detailPath = CosBizService.getDeleteQrCodePath(uploadPath, gatherProject.getId());
                cosBizService.deleteFile(detailPath);
            } catch (Exception e) {
                logger.error("删除自定义信息收集项目二维码失败", e);
            }
        }
        return endResult;
    }
}
